using System;
using System.Text;

using System.IO;
using System.Collections;
using System.Collections.Generic;

namespace Tools.SubStream
{

    /// <summary>
    /// 
    /// </summary>
    public class StreamMuxerException : Exception
    {
        /// <summary>
        /// 
        /// </summary>
        public enum Kind { General, RangeError };

        /// <summary>
        /// 
        /// </summary>
        public Kind kind;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        /// <param name="kind"></param>
        public StreamMuxerException ( String message, StreamMuxerException.Kind kind )
            : base( message )
        {
            this.kind = kind;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public StreamMuxerException ( String message )
            : base( message )
        {
            this.kind = Kind.General;
        }



    }

    /// <summary>
    /// 
    /// </summary>
    public class StreamMuxer
    {

        /// <summary>
        /// 
        /// </summary>
        protected Hashtable subStreams = new Hashtable();

        /// <summary>
        /// 
        /// </summary>
        protected System.IO.Stream innerStream;

        /// <summary>
        /// gets 
        /// </summary>
        public System.IO.Stream InnerStream
        {
            get
            {
                if( this.innerStream == null )
                {
                    throw new StreamMuxerException( "InnerStream not initialised" );
                };
                return this.innerStream;

            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="masterStream"></param>
        public StreamMuxer( System.IO.Stream masterStream )
        {
            this.innerStream = masterStream;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="range"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public MuxerSubStream makeSubStream ( Range range, String name )
        {
            return new MuxerSubStream( this, range, name );
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="range"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public MuxerSubStream addSubStream ( Range range, String name )
        {
            MuxerSubStream substr = this.makeSubStream( range, name );
            this.subStreams.Add( name, substr );
            return substr;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public MuxerSubStream this[String name]
        {
            get
            {
                return this.getSubStream( name );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public MuxerSubStream getSubStream ( String name )
        {
            if( this.subStreams.ContainsKey( name ) )
            {
                return ( MuxerSubStream )this.subStreams[name];
            }
            else
            {
                throw new StreamMuxerException( "no requested substream" );
            }
        }
    }
}
